package com.yic.module.mes.service.itemproduceroute;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.yic.framework.common.util.collection.CollectionUtils;
import com.yic.framework.common.util.collection.MapUtils;
import com.yic.module.mes.controller.admin.itemproducerouteextend.vo.ItemProduceRouteExtendCreateReqVO;
import com.yic.module.mes.controller.admin.itemproducerouteextend.vo.ItemProduceRouteExtendRespVO;
import com.yic.module.mes.controller.admin.processRoute.vo.ProcessRouteDetailRespVo;
import com.yic.module.mes.controller.admin.processrouteinfo.vo.ProcessRouteInfoRespVO;
import com.yic.module.mes.dal.dataobject.itemproducerouteextend.ItemProduceRouteExtendDO;
import com.yic.module.mes.dal.dataobject.processRoute.ProcessRouteDO;
import com.yic.module.mes.dal.dataobject.processrouteinfo.ProcessRouteInfoDO;
import com.yic.module.mes.service.itemproducerouteextend.ItemProduceRouteExtendService;
import com.yic.module.mes.service.processRoute.ProcessRouteService;
import com.yic.module.mes.service.processrouteinfo.ProcessRouteInfoService;
import com.yic.module.system.enums.dict.SystemBooleanEnum;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import com.yic.module.mes.controller.admin.itemproduceroute.vo.*;
import com.yic.module.mes.dal.dataobject.itemproduceroute.ItemProduceRouteDO;
import com.yic.framework.common.pojo.PageResult;

import com.yic.module.mes.convert.itemproduceroute.ItemProduceRouteConvert;
import com.yic.module.mes.dal.mysql.itemproduceroute.ItemProduceRouteMapper;

import static com.yic.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yic.module.mes.enums.ErrorCodeConstants.*;

/**
 * 产品工艺路线 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class ItemProduceRouteServiceImpl implements ItemProduceRouteService {

    @Resource
    private ItemProduceRouteMapper itemProduceRouteMapper;
    @Resource
    private ItemProduceRouteExtendService itemProduceRouteExtendService;
    @Resource
    private ProcessRouteService processRouteService;
    @Resource
    private ProcessRouteInfoService processRouteInfoService;
    @Resource
    private TransactionTemplate transactionTemplate;

    @Override
    public void createItemProduceRoute(List<ItemProduceRouteCreateReqVO> createReqVOs, Long itemProduceId) {
        List<ItemProduceRouteExtendCreateReqVO> list = new ArrayList<>();
        Boolean flag = Boolean.FALSE;
        for (int i = 0; i < createReqVOs.size(); i++) {
            ItemProduceRouteCreateReqVO itemProduceRoute = createReqVOs.get(i);
            if (SystemBooleanEnum.YES.getSystemBoolean().equals(itemProduceRoute.getDefaultRoute()) && flag) {
                throw exception(ITEM_PRODUCE_ONLY_ONE_DEFAULT_ROUTE);
            }
            if (SystemBooleanEnum.YES.getSystemBoolean().equals(itemProduceRoute.getDefaultRoute())) {
                flag = Boolean.TRUE;
            }
            itemProduceRoute.setItemProduceId(itemProduceId);
            //组装扩展数据
            itemProduceRoute.getExtendList().forEach(itemProduceRouteExtendCreateReqVO -> {
                itemProduceRouteExtendCreateReqVO.setItemProduceId(itemProduceId);
                itemProduceRouteExtendCreateReqVO.setRouteId(itemProduceRoute.getRouteId());
            });
            list.addAll(itemProduceRoute.getExtendList());
        }
        if (!flag && CollectionUtil.isNotEmpty(createReqVOs)) {
            throw exception(ITEM_PRODUCE_ONLY_ONE_DEFAULT_ROUTE);
        }
        List<ItemProduceRouteDO> itemProduceRouteDOs = ItemProduceRouteConvert.INSTANCE.convertList03(createReqVOs);
        transactionTemplate.execute(status -> {
            itemProduceRouteMapper.deleteByItemProduceId(itemProduceId);
            itemProduceRouteMapper.insertBatch(itemProduceRouteDOs);
            itemProduceRouteExtendService.createItemProduceRouteExtend(list, itemProduceId);
            return Boolean.TRUE;
        });
    }

    @Override
    public Long createItemProduceRoute(ItemProduceRouteCreateReqVO createReqVO) {
        // 插入
        ItemProduceRouteDO itemProduceRoute = ItemProduceRouteConvert.INSTANCE.convert(createReqVO);
        itemProduceRouteMapper.insert(itemProduceRoute);
        // 返回
        return itemProduceRoute.getId();
    }

    @Override
    public void updateItemProduceRoute(ItemProduceRouteUpdateReqVO updateReqVO) {
        // 校验存在
        validateItemProduceRouteExists(updateReqVO.getId());
        // 更新
        ItemProduceRouteDO updateObj = ItemProduceRouteConvert.INSTANCE.convert(updateReqVO);
        itemProduceRouteMapper.updateById(updateObj);
    }

    @Override
    public void deleteItemProduceRoute(Long id) {
        // 校验存在
        validateItemProduceRouteExists(id);
        // 删除
        itemProduceRouteMapper.deleteById(id);
    }

    private void validateItemProduceRouteExists(Long id) {
        if (itemProduceRouteMapper.selectById(id) == null) {
            throw exception(ITEM_PRODUCE_ROUTE_NOT_EXISTS);
        }
    }

    @Override
    public ItemProduceRouteDO getItemProduceRoute(Long id) {
        return itemProduceRouteMapper.selectById(id);
    }

    @Override
    public List<ItemProduceRouteDO> getItemProduceRouteList(Collection<Long> ids) {
        return itemProduceRouteMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ItemProduceRouteDO> getItemProduceRoutePage(ItemProduceRoutePageReqVO pageReqVO) {
        return itemProduceRouteMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ItemProduceRouteDO> getItemProduceRouteList(ItemProduceRouteExportReqVO exportReqVO) {
        return itemProduceRouteMapper.selectList(exportReqVO);
    }

    @Override
    public List<ItemProduceRouteRespVO> getListByItemProduceId(Long itemProduceId) {
        // 查询产品工艺路线
        List<ItemProduceRouteDO> itemProduceRouteDOS = itemProduceRouteMapper.selectListByItemProduceId(itemProduceId);
        // 查询产品工艺路线配置
        List<ItemProduceRouteExtendRespVO> itemProduceRouteExtendRespVOS = itemProduceRouteExtendService.getItemProduceRouteExtendListByItemProduceId(itemProduceId);


        // 查询工艺路线及工艺路线配置
        Map<Long, ProcessRouteDO> processRouteDOMap = new HashMap<>();
        List<ProcessRouteInfoRespVO> processRouteInfoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(itemProduceRouteDOS)) {
            Set<Long> routeIds = CollectionUtils.convertSet(itemProduceRouteDOS, ItemProduceRouteDO::getRouteId);
            List<ProcessRouteDO> processRouteList = processRouteService.getProcessRouteList(routeIds);
            processRouteDOMap = CollectionUtils.convertMap(processRouteList, ProcessRouteDO::getId);
            //查询工艺路线配置
            processRouteInfoList = processRouteInfoService.getProcessRouteInfoListByRouteId(routeIds);

        }

        //组装数据
        Map<Long, List<ItemProduceRouteExtendRespVO>> extendMap = new HashMap<>();
        if (ObjectUtil.isNotEmpty(processRouteInfoList)) {
            List<ItemProduceRouteExtendRespVO> itemProduceRouteExtends = new ArrayList<>();
            Map<String, ItemProduceRouteExtendRespVO> map = CollectionUtils.convertMap(itemProduceRouteExtendRespVOS, itemProduceRouteExtendRespVO -> {
                return itemProduceRouteExtendRespVO.getRouteId() + "-" + itemProduceRouteExtendRespVO.getProcessId();
            });
            processRouteInfoList.forEach(processRouteInfoRespVO -> {
                ItemProduceRouteExtendRespVO vo = new ItemProduceRouteExtendRespVO();
                vo.setItemProduceId(itemProduceId);
                vo.setRouteId(processRouteInfoRespVO.getRouteId());
                vo.setLink(processRouteInfoRespVO.getLink());
                vo.setMainProcess(processRouteInfoRespVO.getMainProcess());
                vo.setProcessId(processRouteInfoRespVO.getProcessId());
                vo.setNextProcessId(processRouteInfoRespVO.getNextProcessId());
                ItemProduceRouteExtendRespVO extendRespVO = map.get(processRouteInfoRespVO.getRouteId() + "-" + processRouteInfoRespVO.getProcessId());
                if (ObjectUtil.isNotEmpty(extendRespVO)) {
                    vo.setId(extendRespVO.getId());
                    vo.setWorkHours(extendRespVO.getWorkHours());
                    vo.setProcessFile(extendRespVO.getProcessFile());
                }
                itemProduceRouteExtends.add(vo);
            });
            extendMap = CollectionUtils.convertMultiMap(itemProduceRouteExtends, ItemProduceRouteExtendRespVO::getRouteId);

        }

        List<ItemProduceRouteRespVO> resp = new ArrayList<>();
        Map<Long, ProcessRouteDO> finalProcessRouteDOMap = processRouteDOMap;
        Map<Long, List<ItemProduceRouteExtendRespVO>> finalExtendMap = extendMap;
        itemProduceRouteDOS.forEach(itemProduceRouteDO -> {
            ItemProduceRouteRespVO itemProduceRouteRespVO = new ItemProduceRouteRespVO();
            itemProduceRouteRespVO.setRouteId(itemProduceRouteDO.getRouteId());
            itemProduceRouteRespVO.setId(itemProduceRouteDO.getId());
            itemProduceRouteRespVO.setDefaultRoute(itemProduceRouteDO.getDefaultRoute());
            ProcessRouteDO processRouteDO = finalProcessRouteDOMap.get(itemProduceRouteDO.getRouteId());
            if (ObjectUtil.isNotEmpty(processRouteDO)) {
                itemProduceRouteRespVO.setRouteCode(processRouteDO.getCode());
                itemProduceRouteRespVO.setRouteName(processRouteDO.getName());
            }
            itemProduceRouteRespVO.setExtendList(finalExtendMap.get(itemProduceRouteDO.getRouteId()));
            resp.add(itemProduceRouteRespVO);
        });
        return resp;
    }

    @Override
    public List<ItemProduceRouteDO> getItemProduceRouteListByItemProduceId(Collection<Long> ids) {
        return itemProduceRouteMapper.selectListByItemProduceId(ids);
    }

    @Override
    public boolean checkUseRoute(Long routeId) {
        ItemProduceRouteDO itemProduceRouteDO = itemProduceRouteMapper.selectOneByRouteId(routeId);
        return ObjectUtil.isNotEmpty(itemProduceRouteDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteItemProduceRouteByItemId(Long itemProduceId) {
        itemProduceRouteExtendService.deleteItemProduceRouteExtendByItemProduceId(itemProduceId);
        return itemProduceRouteMapper.deleteByItemProduceId(itemProduceId);
    }


}
